package com.mec.fileTransfer.core;

import java.io.DataOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.net.Socket;
import java.util.List;

import com.mec.about_file.util.ByteAndString;

public class ResourceSender implements Runnable {
	public static final int BUFFER_SIZE = 1 << 15;
	
	private Socket socket;
	private DataOutputStream dos;
	private List<SendFileModel> sendFileList;
	private ReceiveFileSet sendFileSet;
	
	//初始化dos端口，并根据带参构造的参数进行成员注入，并在最后启动发送线程进行发送
	ResourceSender(Socket socket, ReceiveFileSet sendFileSet,
			List<SendFileModel> sendFileList) throws IOException {
		this.socket = socket;
		this.sendFileSet = sendFileSet;
		this.sendFileList = sendFileList;
		dos = new DataOutputStream(socket.getOutputStream());
		new Thread(this, "ResourceSender").start();
	}

	void close() {
		try {
			if (dos != null) {
				dos.close();
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			dos = null;
		}
		try {
			if (socket != null && !socket.isClosed()) {
				socket.close();
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			socket = null;
		}
	}
	
	@Override
	public void run() {
		//实际文件发送进程
		//如果文件是空，则返回
		if (sendFileList == null) {
			return;
		}
		
		//文件头部，16字节：4文件编号 8偏移量 4文件长度
		byte[] header = new byte[16];
		//分块长度：BUFFER_SIZE
		byte[] buffer = new byte[BUFFER_SIZE];
		
		for (SendFileModel sendFile : sendFileList) {
			
			String absolutePath = sendFile.getAbsoluteRootPath();
			String filePath = sendFile.getFilePath();
			int fileNo = sendFileSet.getFileNo(absolutePath + filePath);
			long offset = sendFile.getOffset();
			int length = sendFile.getLength();
			
			ByteAndString.setIntAt(header, 0, fileNo);
			ByteAndString.setLongAt(header, 4, offset);
			ByteAndString.setIntAt(header, 12, length);
			
			try {
				//先发送16字节文件头部
				dos.write(header);
				dos.flush();
				
				//读方式打开文件
				RandomAccessFile raf = new RandomAccessFile(
						absolutePath + filePath, "r");
				raf.seek(offset);
				int len = 0;
				int realReadLen = 0;
				
				while (length > 0) {
					realReadLen = length >= BUFFER_SIZE
							? BUFFER_SIZE : length;
					len = raf.read(buffer, 0, realReadLen);
					dos.write(buffer, 0, len);
					length -= len;
				}
				
				raf.close();
			} catch (IOException e) {
				e.printStackTrace();
				close();
				break;
			}
		}
		
		//发送文件内容完毕，再发送一个header进行发送完毕的情况说明
		ByteAndString.setIntAt(header, 0, -1);
		ByteAndString.setLongAt(header, 4, 0);
		ByteAndString.setIntAt(header, 12, 0);
		try {
			if (dos != null) {
				dos.write(header);
				dos.flush();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		close();
	}
	
}
